# -*- coding: utf-8 -*-
'''
Created on 2013-4-11
@author: cl.lam
'''

import traceback
from datetime import datetime as dt
from flask import current_app as app
from flask import g, render_template, flash, session, redirect, url_for, request
from flask.blueprints import Blueprint
from sqlalchemy.sql.expression import and_, not_
from sqlalchemy.orm.exc import NoResultFound


from sys2do.views import BasicView
from sys2do.util.decorator import templated, loginRequired, activetab
from sys2do.model import Currency, SysLog, qry, db, CurrencyRatio

from sys2do.util.common import _g, _gld, _gp, _gl
from sys2do.constant import MSG_SAVE_SUCC, TAB_BASIC, TAB_FLAG, LOG_TYPE_CREATE, \
    MESSAGE_INFO, MSG_SERVER_ERROR, MESSAGE_ERROR, MSG_NO_ID_SUPPLIED, \
    MSG_RECORD_NOT_EXIST, MSG_UPDATE_SUCC, LOG_TYPE_UPDATE, \
    MSG_NOT_ENOUGH_PARAMS, MSG_SAME_NAME_RECORD_EXIST
from sys2do.util.logic_helper import makeUpdateLog, getCurrentUserID





__all__ = ['bpCry']

bpCry = Blueprint( 'bpCry', __name__ )
@bpCry.before_request
def addActivetab():    session[TAB_FLAG] = TAB_BASIC


class CurrencyView( BasicView ):

    template_folder = "mas.cry"

    dbclz = Currency

    @templated( "index.html" )
    @loginRequired
    def index( self ):
        form = SrhForm( request.form )
        form.url = url_for( '.view' )

        cds = [ self.dbclz.active == 0, ]
        if form.no.data : cds.append( self.dbclz.no.like( '%%%s%%' % form.no.data ) )
        if form.code.data : cds.append( self.dbclz.code.like( '%%%s%%' % form.code.data ) )
        if form.name.data : cds.append( self.dbclz.name.like( '%%%s%%' % form.name.data ) )
        if form.createTimeFrom.data : cds.append( self.dbclz.createTime > form.createTimeFrom.data )
        if form.createTimeTo.data : cds.append( self.dbclz.createTime < form.createTimeTo.data )

        result = qry( self.dbclz ).filter( and_( *cds ) ).order_by( self.dbclz.no )
        return {'result' : result , 'form' : form}


    @templated( 'view.html' )
    def view( self ):
        cid = _g( 'id' )
        if not cid :
            flash( MSG_NO_ID_SUPPLIED, MESSAGE_ERROR )
            return redirect( url_for( ".view" ) )

        obj = self.dbclz.get( cid )
        if not obj :
            flash( MSG_RECORD_NOT_EXIST, MESSAGE_ERROR )
            return redirect( url_for( ".view" ) )
        return {'obj' : obj}




    @templated( "add.html" )
    @loginRequired
    def add( self ):
        if request.method != 'POST': return {}

        params = _gld( 'code', 'name', 'remark', 'isDefault' )
        if self._isDuplicate( params['code'] ) : return redirect( url_for( '.view', action = 'add' ) )

        try:
            if params['isDefault']: qry( Currency ).update( {Currency.isDefault : 0} )
            obj = Currency.create( params )
            robj = CurrencyRatio.create( {'currency' : obj , 'ratio' : _g( 'ratio' )} )
            db.add_all( [obj, robj] )
            db.flush()
            db.add( SysLog( refClz = obj.__class__.__name__, type = LOG_TYPE_CREATE, refID = obj.id, ) )
            db.commit()
            flash( MSG_SAVE_SUCC, MESSAGE_INFO )
        except:
            traceback.print_exc()
            db.rollback()
            flash( MSG_SERVER_ERROR, MESSAGE_ERROR )
        return redirect( url_for( ".view" ) )



    @templated( "update.html" )
    @loginRequired
    def update( self ):
        cid = _g( 'id' )
        if not cid :
            flash( MSG_NO_ID_SUPPLIED, MESSAGE_ERROR )
            return redirect( url_for( ".view" ) )

        obj = self.dbclz.get( cid )
        if not obj :
            flash( MSG_RECORD_NOT_EXIST, MESSAGE_ERROR )
            return redirect( url_for( ".view" ) )

        if request.method != 'POST': return {'obj' : obj}

        try:
            oldCopy = obj.serialize()
            params = _gld( 'code', 'name', 'remark', 'isDefault' )
            params['updateTime'] = dt.now()
            params['updateById'] = getCurrentUserID()
            if params['isDefault']: qry( Currency ).update( {Currency.isDefault: 0} )

            obj.update( params )
            newCopy = obj.serialize()
            makeUpdateLog( obj, oldCopy, newCopy )

            et = _gl( 'et' )
            if et :
                # effect immediately
                if et[0] == '0' :
                    db.add( CurrencyRatio( currency = obj, ratio = _g( 'ratio' ), effTime = dt.now() ) )
                    obj.ratio = _g( 'ratio' )    # update the ratio now
                else:
                    effTime, ratio = _g( 'effTime' ), _g( 'ratio' )
                    try:
                        robj = qry( CurrencyRatio ).filter( and_( CurrencyRatio.active == 0 , CurrencyRatio.currencyID == obj.id,
                                                           CurrencyRatio.effTime == effTime + ' 00:00:00' ) ).one()
                        robj.ratio = ratio
                    except NoResultFound:
                        db.add( CurrencyRatio.create( dict( currency = obj, ratio = ratio, effTime = effTime ) ) )
            db.add( SysLog( refClz = obj.__class__.__name__, type = LOG_TYPE_UPDATE, refID = obj.id, ) )
            db.commit()
            flash( MSG_UPDATE_SUCC, MESSAGE_INFO )
        except:
            traceback.print_exc()
            db.rollback()
            flash( MSG_SERVER_ERROR, MESSAGE_ERROR )
        return redirect( url_for( ".view", action = "view", id = obj.id ) )


    def _isDuplicate( self, code ):
        try:
            qry( self.dbclz ).filter( self.dbclz.code == code ).one()
        except:
            return False
        else:
            flash( MSG_SAME_NAME_RECORD_EXIST, MESSAGE_ERROR )
            return True


bpCry.add_url_rule( '/', view_func = CurrencyView.as_view( 'view' ), defaults = {'action':'index'} )
bpCry.add_url_rule( '/<action>', view_func = CurrencyView.as_view( 'view' ) )

#===============================================================================
# form class
#===============================================================================

from wtforms import Form, TextField
from sys2do.util.wt_helper import MyDateField

class SrhForm( Form ):
    no = TextField( u'系统编号', )
    code = TextField( u'货币代码', )
    name = TextField( u'货币名称', )
    createTimeFrom = MyDateField( u'创建时间(开始)' )
    createTimeTo = MyDateField( u'创建时间(结束)' )
